package io.sundial.engine.impl;

import io.sundial.core.AtomicVTCommand;
import io.sundial.core.lifecycle.Stateful;
import io.sundial.engine.Engine;
import io.sundial.engine.exception.ShuttingException;
import io.sundial.engine.exception.StartingException;

import java.util.concurrent.atomic.AtomicReference;

import static io.sundial.engine.Engine.Status.*;

/**
 * 抽象引擎实现
 *
 * @author Payne 646742615@qq.com
 * 2018/12/20 10:11
 */
public abstract class StatefulEngine extends Stateful implements Engine {
    private final AtomicReference<Status> status = new AtomicReference<>(WAITING);

    @Override
    public Status status() {
        return status.get();
    }

    @Override
    public void startup() throws StartingException {
        doWritingCommand(new AtomicVTCommand<StartingException>() {
            @Override
            public void run() throws StartingException {
                if (!status.compareAndSet(WAITING, STARTING_UP)) {
                    throw new StartingException("the io.sundial.engine is " + status.get());
                }
                starting();
                status.set(RUNNING);
            }
        });
    }

    protected void starting() throws StartingException {

    }

    @Override
    public void shutdown() throws ShuttingException {
        doWritingCommand(new AtomicVTCommand<ShuttingException>() {
            @Override
            public void run() throws ShuttingException {
                if (!status.compareAndSet(RUNNING, SHUTTING_DOWN)) {
                    throw new ShuttingException("the io.sundial.engine is " + status.get());
                }
                shutting();
                status.set(TERMINATED);
            }
        });
    }

    protected void shutting() throws ShuttingException {

    }

}
